import React, { useEffect, useState, useImperativeHandle } from 'react';
import 'antd/lib/table/style/index.css';
import { Table } from 'antd4';
import { Input, Tooltip } from 'antd';
const { Search } = Input;
import classNames from 'classnames';
import styles from './index.less';
import { request } from '@zny/utils';
import _ from 'lodash'
import Highlighter from "react-highlight-words";

type Key = string | number

type rowKeyNames = "sourceCode" | "sourceName" | "id"

export interface IRourseceItem {
  sourceCode: string | number,
  sourceName: string,
  id: string | number,
  children: [],
  hasChildren: boolean,
  unit: string,
  parentId: string | number,
  [propName: string]: string | number | boolean | [],

}

export interface IProp {
  checkedKeyList?: Key[],
  disableKeyList?: Key[],
  onSelect?: (list: IRourseceItem[], keyList: Key[]) => void,
  rowKeyName: rowKeyNames,
  scroll?: Iscroll,
  initFetch?: (list: IRourseceItem[]) => void,
  dataLoading: Boolean,
  //设备 材料
  sourceType?: 'device' | 'material'
}

interface Iscroll {
  x: string | number,
  y: string | number,
  scrollToFirstRowOnChange: boolean
}



const TreeData: React.FC<IProp> = React.forwardRef((props, ref) => {
  let columns: any[] = []
  if (props.sourceType === 'material') {
    columns = [
      {
        title: '材料资源编码',
        dataIndex: 'sourceCode',
        key: "sourceCode",
        width: 245,
        textWrap: 'word-break',
        ellipsis: true,
        render: (text: string) => (
            <Highlighter
              highlightClassName={classNames(styles.xmark)}
              searchWords={[searchTxt]}
              textToHighlight={text}
            />
        ),
      },
      {
        title: '材料资源名称',
        dataIndex: 'sourceName',
        key: "sourceName",
        render: (text: string) => (
          <Highlighter
            highlightClassName={classNames(styles.xmark)}
            searchWords={[searchTxt]}
            textToHighlight={text}
          />
        ),
      },
      {
        title: '单位',
        dataIndex: 'unit',
        key: "unit"
      },
      {
        title: '备注',
        dataIndex: 'remark',
        key: "remark"
      }
    ];
  } else if (props.sourceType === 'device') {
    columns = [
      {
        title: '材料资源名称',
        dataIndex: 'sourceName',
        key: "sourceName",
        render: (text: string) => (
          <Highlighter
            highlightClassName={classNames(styles.xmark)}
            searchWords={[searchTxt]}
            textToHighlight={text}
          />
        ),
      },
      {
        title: '单位',
        dataIndex: 'unit',
        key: "unit"
      },
      {
        title: '规格型号',
        dataIndex: 'standardType',
        key: "standardType"
      }
    ];
  }

  const rowSelection = {
    hideSelectAll: true,
    onChange: (selectedRowKeys: Key[], selectedRows: IRourseceItem[]) => {
      //selectedRowKeys只有选中得接口 不含半选父级

      setSelectedRowKeys(selectedRowKeys)
      if (props.onSelect && typeof props.onSelect === 'function') {
        // let list = getLeafFormSelectedRow(selectedRowKeys)
        let itemList = getLeafFormSelectedRowItem(selectedRows)
        props.onSelect(itemList, selectedRowKeys)
      }
    },
    getCheckboxProps(record: IRourseceItem) {
      return setDisable(record)
    }
  };
  let [treeData, setTreeData] = useState<IRourseceItem[]>([])
  let [oriTreeData, setOriTreeData] = useState<IRourseceItem[]>([])
  let [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([])
  let [searchTxt, setSearchTxt] = useState<string>('')
  let [loadingTree, setLoadingTree] = useState<boolean>(false)
  const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([])
  const fetchData = async () => {
    setLoadingTree(true)
    let data = await request('/api/Resource/Material/GetSubmitTreeData', {
      method: 'post',
      data: []
    });
    setLoadingTree(false)
    setOriTreeData(data)
  }

  const fetchDevice = async () => {
    setLoadingTree(true)
    let data = await request('/api/Device/DeviceDetail/GetList', {
      method: 'post',
      data: {
        requireTotalCount: true,
        skip: 0,
      }
    });
    let transData = transDeviceData(data.data)
    setOriTreeData(transData)
    setLoadingTree(false)
  }

  const transDeviceData = (data: any) => {
    return data.map((item: any) => {
      return {
        hasChildren: false,
        id: item.id,
        level: 0,
        orderIndex: null,
        parentId: null,
        sourceCode: "",
        sourceName: item.deviceName,
        standardType: item.standardType,
        unit: "吨"
      }
    })
  }

  const getLeafFormSelectedRow = (selectedRowKeys: Key[], tree?: IRourseceItem[]) => {

    let res: IRourseceItem[] = []
    let rowKeyName = props.rowKeyName
    if (rowKeyName == null) {
      rowKeyName = "id"
    }
    if (tree == null) {
      tree = treeData
    }
    for (let i = 0, len = tree.length; i < len; i++) {
      const item = tree[i];

      if (selectedRowKeys.indexOf(item[rowKeyName]) !== -1) {
        if (!item.hasChildren) {
          res.push(item)
        } else {
          if (item.children && Array.isArray(item.children)) {
            res = res.concat(...getLeafFormSelectedRow(selectedRowKeys, item?.children))
          } else {
            console.error("数据格式错误", item)
          }
        }
      }
    }
    return res
  }

  const getLeafFormSelectedRowItem = (list: IRourseceItem[]) => {
    return list.filter(item => {
      if (item.hasChildren && item.children && Array.isArray(item.children) && item.children.length > 0) {
        return false
      }
      return true
    })
  }

  const setRowKey = (record: IRourseceItem) => {
    let rowKeyName = props.rowKeyName
    if (rowKeyName == null) {
      rowKeyName = "id"
    }
    return record[rowKeyName]
  }

  const setDisable = (record: IRourseceItem) => {
    let rowKeyName = props.rowKeyName
    if (rowKeyName == null) {
      rowKeyName = "id"
    }
    let keyName = record[rowKeyName]
    if (props.disableKeyList == null) {
      props.disableKeyList = []
    }



    if (props.disableKeyList.indexOf(keyName) !== -1) {
      return { disabled: true }
    } else {
      if (record.hasChildren && record.children && record.children.length > 0) {
        if (checkAllChildDisAble(record.children)) {
          return { disabled: true }
        }
      }
    }

    return null
  }

  //计算效率太低了
  function checkAllChildDisAble(list: IRourseceItem[]): boolean {
    let rowKeyName = props.rowKeyName
    if (rowKeyName == null) {
      rowKeyName = "id"
    }
    let hasNoPass = list.some(item => {

      let keyName = item[rowKeyName]
      if (props.disableKeyList.indexOf(keyName) === -1) {
        return true
      }

      if (item.hasChildren && item.children && item.children.length > 0) {
        return checkAllChildDisAble(item.children)
      }
      return false
    })
    return !hasNoPass
  }

  const filterTree = (str: string, tree: IRourseceItem[]): IRourseceItem[] => {
    if (str == null || str.length === 0) return tree
    let res: IRourseceItem[] = []

    let rowKeyName = props.rowKeyName
    if (rowKeyName == null) {
      rowKeyName = "id"
    }
    for (let i = 0, len = tree.length; i < len; i++) {
      const item = tree[i];

      //如果code 或者 name 包含这个值
      if (String(item.sourceCode).indexOf(str) !== -1 || String(item.sourceName).indexOf(str) !== -1) {
        res.push(item)
      } else if (selectedRowKeys?.indexOf(item[rowKeyName]) !== -1) {
        res.push(item)
      } else {
        if (item.hasChildren && item.children && item.children.length > 0) {
          let result = filterTree(str, item.children);
          if (result.length > 0) {
            //剔除掉不包含的子值
            let filterItem = _.cloneDeep(item)
            filterItem.children = result
            res.push(filterItem)
          }
        }
      }
    }
    return res
  }

  const handleSearch = (val: string) => {
    setSearchTxt(val)
  }

  const handleChangeTxt = (e) => {
    let { value } = e.target
    setSearchTxt(value)
  }

  function getTreeKeys(tree: IRourseceItem[]) {
    let list: string[] = []
    let rowKeyName = props.rowKeyName
    for (let i = 0; i < tree.length; i++) {
      let item = tree[i]
      list.push(item[rowKeyName])
      if (item.hasChildren && item.children && Array.isArray(item.children) && item.children.length > 0) {

        let result = getTreeKeys(item.children)
        list = list.concat(result)
      }
    }
    return list
  }

  useEffect(() => {
    let res: IRourseceItem[] = filterTree(searchTxt, oriTreeData)
    let keyslist = getTreeKeys(res)
    setExpandedRowKeys(keyslist)
    setTreeData(res)
  }, [searchTxt])

  useEffect(() => {
    switch (props.sourceType) {
      case 'device':
        fetchDevice()
        break;
      case 'material':
        fetchData()
        break;
      default:
        fetchData()
        break;
    }

  }, [])

  useEffect(() => {
    setSelectedRowKeys(props.checkedKeyList ? props.checkedKeyList : [])
    setTreeData(oriTreeData)
  }, [oriTreeData])

  useEffect(() => {
    setSelectedRowKeys(props.checkedKeyList ? props.checkedKeyList : [])
  }, [props.checkedKeyList])

  function clearRowKeys() {
    setSelectedRowKeys([])
  }

  React.useImperativeHandle(ref, () => ({
    clearRowKeys,
    clearSearchTxt: () => {
      setSearchTxt('')
    }
  }));

  return (
    <div className={classNames(styles.antd4Wrap)}>
      <div
        style={{
          textAlign: "right",
          marginBottom: 10
        }}>
        <Search
          style={{ width: 400 }}
          enterButton="搜索"
          placeholder="请输入名称进行查询"
          value={searchTxt}
          onSearch={(val) => handleSearch(val)}
          onChange={e => handleChangeTxt(e)} />

      </div>
      <Table
        style={{
          height: 400
        }}
        expandable={{
          expandedRowKeys,
          rowExpandable: () => true
        }}
        pagination={false}
        columns={columns}
        loading={loadingTree}
        rowSelection={{ ...rowSelection, checkStrictly: false, selectedRowKeys }}
        scroll={
          {
            y: 360,
            scrollToFirstRowOnChange: true
          }
        }
        dataSource={treeData}
        rowKey={setRowKey}
        onExpand={(expanded, record) => {
          let rowKeyName = props.rowKeyName
          let rowKey = record[rowKeyName] + ''
          if (expanded) {
            setExpandedRowKeys(oldState => {
              if (oldState.indexOf(rowKey) === -1) {
                oldState.push(rowKey)
              }
              return oldState
            })
          } else {
            setExpandedRowKeys(oldState => {
              return oldState.filter(item => item !== rowKey)
            })
          }
        }}
      />
    </div>
  );
})

TreeData.defaultProps = {
  rowKeyName: 'id',
  sourceType: 'material'
}

export default TreeData